iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0

概述: 從微服務角度調整系統架構

  • 延續上一篇的需求,嘗試以微服務的理念調整架構。
  • 最主要的變動是將AWS Lambda Function從Spring Boot改成較為輕量級的Node.js,並使用 Message Queue 將系統拆分為 Producer 和 Consumer 兩個角色,讓兩邊的程式邏輯簡單化,減少相依性,提高維護性和可擴充性。

架構調整需求: 維護性及可擴充性

雖然系統規模不大,我還是希望它能具備像商業系統一樣的運作標準。相關的理論相當多,但我認為直接能做到的,就是依照微服務的主要精神,盡量把系統拆成幾個小範圍、無狀態,且能獨自運作的服務,這樣的設計能方便的抽換服務和水平擴展。

延遲問題

此系統包含一些需要考慮輸入輸出(IO) 及 API 延遲的任務,例如呼叫 Open AI API以及資料庫 IO的延遲等。這些任務的延遲時間較不穩定,不適合擺在AWS Lambda 上執行,因為 Lambda Function 有執行時間的限制(雖然可以調整)。例如早期的Open AI API在prompt字數較多時,偶爾會有多達5秒的延遲,會造成額外的執行成本。

  • 根據AWS Lambda目前的定價標準,若Function執行時間和程式量導致儲存個體超過512MB時,就會開始計費:【 Lambda 定價頁面】

解耦合

另外,將事件接收/處理,及其他Bot Server的核心邏輯綁在一起,程式結構會比較複雜,當出現錯誤需要Debug時,比較不容易分清楚是哪一段程式出了問題。
後續要修改相關功能時,也可能會因為過多的相依性造成額外的維護難度。

實作: 具體的技術選擇與架構調整

https://ithelp.ithome.com.tw/upload/images/20240918/201052270imNRBZJOX.png
為了因應上述需求,我做了以下調整:

Producer and Consumer 模式: 將事件處理與Bot Server解耦

Producer: 事件處理

  • 這部分在AWS Lambda上執行,專注於從Webhook事件中提取使用者輸入的訊息內容、Token,及其他Client端資訊。
  • 如果提取成功,會將相關資訊送到Message Queue,任務就算完成; 若資料有誤或提取失敗,則直接返回,不觸發後續邏輯。
  • 可擴充性: 由於是在Lambda上執行,可以依照使用需求調整並行配額,預設為1000個

Consumer: Bot Server

  • 這部分在AWS EC2上執行,專注於語意判斷及後續邏輯處理。
  • 一旦Message Queue有任務,就會取得使用者訊息及Token,經過處理後,使用LINE的API帶上Token回傳結果給使用者。
  • Producer 和 Consumer 相互獨立,並不直接呼叫Consumer這邊的Function,所以沒有相依性的問題。
  • 可擴充性: Bot Server不具備狀態,只要能讀取的到Kafka中的資料,就能繼續運行,若有需要可隨時依需求升級 / 擴充EC2,執行多個Bot Server。

Message Queue

  • 使用Kafka作為訊息佇列,負責Producer 和 Consumer 之間的溝通。

AWS Lambda 事件處理:從 Spring Boot 換成 Node.js

原本使用的Spring Boot必須將程式與依賴包打包成 Uber Jar,才能在 Lambda 上執行。由於這種執行檔無論在執行時間和大小都比較大,不適合做成Lambda Function。故換成檔案較小,更輕量的Node.js作為事件處理的程式語言。

OpenAI的語意辨識從Lambda移至到Bot Server

由於此專案是用Call API的方式實現OpenAI的語意辨識,故會有延遲時間的不確定性,導致在 Lambda 上的執行時間過長。因此,我將語意辨識的功能從 Lambda 移到 Bot Server 上執行。

資料庫選擇:使用 NoSQL (MongoDB)

由於目前的專案需求較為單純,沒有什麼constraint需要限制,也沒有太多資料表同做更動需要的Transaction,故RDBMS提供的原子性(Atomicity) 和 一致性(Consistency)暫時用不到,易用性和水平擴展的靈活性才是更重要的,故資料庫使用MongoDB。


上一篇
架構描述: 專案緣起
下一篇
LINE Bot 基本觀念: 運作原理
系列文
從零開始構建能理解語義的 Linebot 架構30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言